/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package fourbox.client;

import fourbox.Metafile;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author hartono
 */
public class ClientMonitor implements Runnable {

    public static final String DEFAULT_WORK_DIR = "D:/FourBox/";
    public ArrayList<Metafile> lastList;
    ArrayList<Metafile> metafiles;
    public List diffs = null;
    File workDir = null;
    public boolean monitorOn = true;

    public static void main(String args[]) {
        ClientMonitor clMonitor = new ClientMonitor();
        Thread clMonitorThread = new Thread(clMonitor);
        clMonitorThread.start();

    }

    public ClientMonitor() {
        workDir = new File(DEFAULT_WORK_DIR);
        diffs = Collections.synchronizedList(new ArrayList());
    }

    public ClientMonitor(String workingPath) {
        diffs = Collections.synchronizedList(new ArrayList());
        workDir = new File(workingPath);
    }

    public synchronized List getDiffs() {
        return diffs;
    }

    @Override
    public void run() {
        System.out.println("Monitor : Starting ...");
        if (workDir.exists()) {
            System.out.println("Monitor : Work directory exist");
            // crawl dulu
            lastList = this.crawlFolder(workDir);
            while (monitorOn) {
                if (diffs.size() == 0) {
                    try {
                        // crawl                    
                        // bandingkan antara dua hasil crawl, ada perubahan atau tidak?
                        // ada 3 kasus
                        // 1. sama
                        // 2. ada file di lama, tapi d baru tidak ada, berarti delete
                        // 3. ada file di baru, tapi tidak ada di lama, berarti update                    

                        // invoke message ke thread koneksi client-server
                        metafiles = this.crawlFolder(workDir);

                        // bandingkan 
                        diffChanges(metafiles, lastList);
                        if (diffs.size() > 0) {
//                            System.out.println("-----------------" + System.currentTimeMillis() + " " + diffs.size());
//                            Iterator it = diffs.iterator();
//                            while (it.hasNext()) {
//                                Metafile m = (Metafile) it.next();
//                                System.out.println(m);
//                            }
                        }
                        Thread.sleep(3000);                        
                        lastList = metafiles;
                        System.out.println("Monitor : checking...");

                    } catch (InterruptedException ex) {
                        Logger.getLogger(ClientMonitor.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        }
        System.out.println("Monitor : Closing...");
    }

    public ArrayList<Metafile> crawlFolder(File folder) {
        Stack<File> queue = new Stack<File>();
        ArrayList<Metafile> retval = new ArrayList<Metafile>();
        queue.add(folder);
        while (!queue.isEmpty()) {
            File head = queue.pop();
            if (head.isDirectory()) {
                File[] files = head.listFiles();
                for (File f : files) {
                    queue.push(f);
                }
            }
//            retval.add(Metafile.createMetafile(head));
            if (folder!=head){
                retval.add(Metafile.createMetafile(workDir.toString(),head));
            }
            
        }
        retval.remove(0);
        return retval;
    }

    public synchronized void diffChanges(ArrayList<Metafile> nMetafiles, ArrayList<Metafile> oMetafiles) {
        diffs.clear();
        for (Metafile oldM : oMetafiles) {

            boolean found = false;
            for (Metafile newM : nMetafiles) {
                if (oldM.directory.equals(newM.directory)) {

                    found = true;
                    break;
                }
            }

            if (found) {
            } else {
//                System.out.println("File not found, deleted");
                // file tidak ditemukan
                // artinya file lama oldM sudah didelete
                oldM.status = Metafile.DELETED;
                diffs.add(oldM);
            }
        }

        // pengecekan file baru terhadap file lama
        for (Metafile newM : nMetafiles) {

            boolean found = false;
            Metafile old = null;
            for (Metafile oldM : oMetafiles) {
                if (newM.directory.equals(oldM.directory)) {
                    old = oldM;
                    found = true;
                    break;
                }
            }

            if (found) {
                // cek sum dulu
                // kalo beda, berarti berubah
                if (newM.size != old.size) {
//                    System.out.println("File updated");
                    newM.status = Metafile.UPDATED;
                    diffs.add(newM);
                }
                // cek tanggal
                // kalo lebih besar, lebih baru
                // kalo lebih kecil, lebih lama
                // kalo sama, yasudah lah                

            } else {
//                System.out.println("File not found, create new file");
                // not found
                // berarti ada file baru
                newM.status = Metafile.NEW;
                diffs.add(newM);
            }
        }

    }
}
